package com.nbjtjc.safe.service.danger;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.nbjtjc.common.bean.*;
import com.nbjtjc.safe.activiti.model.DangerProcess;
import com.nbjtjc.safe.bean.Constant;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.mapper.danger.DangerInspectListPublicMapper;
import com.nbjtjc.safe.mapper.danger.DangerInspectPublicMapper;
import com.nbjtjc.safe.mapper.safe.SafeDangerInspectTaskMapper;
import com.nbjtjc.safe.mapper.safe.SafeDangerInspectTaskRecordMapper;
import com.nbjtjc.safe.mapper.sys.SysDeptMapper;
import com.nbjtjc.safe.mapper.sys.SysFileMapper;
import com.nbjtjc.safe.model.danger.DangerInspectListPublic;
import com.nbjtjc.safe.model.danger.DangerInspectPublic;
import com.nbjtjc.safe.model.safe.SafeDangerInspectTask;
import com.nbjtjc.safe.model.safe.SafeDangerInspectTaskRecord;
import com.nbjtjc.safe.model.sys.SysDept;
import com.nbjtjc.safe.model.sys.SysFile;
import com.nbjtjc.safe.service.sys.SysDeptService;
import com.nbjtjc.safe.util.MyShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @auther guqianbin
 * @date 2018/4/12 11:28
 **/
@Service
public class DangerInspectListPublicService {
    @Autowired
    private DangerInspectListPublicMapper dangerInspectListPublicMapper;
    @Autowired
    private SysFileMapper sysFileMapper;
    @Autowired
    private SysDeptMapper sysDeptMapper;
    @Autowired
    private SysDeptService sysDeptService;

    @Autowired
    private DangerInspectPublicMapper dangerInspectPublicMapper;

    @Autowired
    private SafeDangerInspectTaskRecordMapper taskRecordMapper;

    @Autowired
    private SafeDangerInspectTaskMapper taskMapper;
    @Value("${aliyun.oss.domain}")
    private String ossDomain;
    @Transactional(rollbackFor = Throwable.class)
    public Result add(DangerInspectListPublic dangerInspectListPublic) {
        Result result = new Result();
        dangerInspectListPublic.setCreateTime(new Date());
        dangerInspectListPublicMapper.insertSelective(dangerInspectListPublic);
        return result;
    }

    @Transactional(rollbackFor = Throwable.class)
    public Result delete(DangerInspectListPublic dangerInspectListPublic) {
        Result result = new Result();
        dangerInspectListPublicMapper.deleteByPrimaryKey(dangerInspectListPublic);
        return result;
    }

    @Transactional(rollbackFor = Throwable.class)
    public Result update(DangerInspectListPublic dangerInspectListPublic) {
        Result result = new Result();
        dangerInspectListPublicMapper.updateByPrimaryKeySelective(dangerInspectListPublic);
        return result;
    }

    @Transactional(rollbackFor = Throwable.class)
    public Result updateList(List<DangerInspectListPublic> dangerInspectListPublics) {
        Result result = new Result();
        dangerInspectListPublics.forEach(dangerInspectListPublic -> {
            dangerInspectListPublicMapper.updateByPrimaryKeySelective(dangerInspectListPublic);
        });
        return result;
    }

    @Transactional(rollbackFor = Throwable.class)
    public Result updateListAndTaskRecord(DangerInspectPublic dangerInspectPublic) {
        Result result = new Result();
        updateInspectTableStatus(dangerInspectPublic);
        List<DangerInspectListPublic> inspectListPublicList=dangerInspectPublic.getDangerInspectListPublicList();
        inspectListPublicList.forEach(dangerInspectListPublic -> {
            dangerInspectListPublic.setCreateTime(new Date());
            dangerInspectListPublic.setActionUserId(MyShiroUtils.getSessionUserId());
            dangerInspectListPublic.setActionUsername(MyShiroUtils.getSessionUserName());
            dangerInspectListPublicMapper.updateByPrimaryKeySelective(dangerInspectListPublic);
        });
        if (CollectionUtil.isNotEmpty(inspectListPublicList)
        &&dangerInspectPublic.getStatus().equals(TASKTABLESTATUS.OVER.getCode())) {
            addRecordByInspectList(dangerInspectPublic.getTaskId(),inspectListPublicList);
        }
        return result;
    }

    private void updateInspectTableStatus(DangerInspectPublic dangerInspectPublic){
        if(dangerInspectPublic.getStatus().equals(TASKTABLESTATUS.OVER.getCode())){
            dangerInspectPublic.setFinish(true);
        }
        dangerInspectPublicMapper.updateByPrimaryKeySelective(dangerInspectPublic);

    }
    private boolean addRecordByInspectList(Integer taskId ,List<DangerInspectListPublic> inspectListPublicList) {
        final Map<String,Integer> dangerCountMap=new HashMap<>();
        dangerCountMap.put("dangerCount",0);
        dangerCountMap.put("inspectCount",0);
        if (CollectionUtil.isNotEmpty(inspectListPublicList)) {
            List<SafeDangerInspectTaskRecord> recordList = new ArrayList<>();
            SafeDangerInspectTask task=taskMapper.selectByPrimaryKey(taskId);
            inspectListPublicList.forEach(listPublic -> {
                SafeDangerInspectTaskRecord taskRecord = new SafeDangerInspectTaskRecord();
                taskRecord.setCreateTime(new Date());
                taskRecord.setInspectTaskId(taskId);
                taskRecord.setInspectResult(listPublic.getInspectResultCode());
                taskRecord.setRecordFrom(RECORDFROMENUM.TABLE.getCode());
                taskRecord.setInspectContent(listPublic.getInspectContent());
                taskRecord.setType(RECORDTYPEENUM.SUBMIT.getCode());
                taskRecord.setActionUserId(MyShiroUtils.getSessionUserId());
                taskRecord.setActionUsername(MyShiroUtils.getSessionUserName());
                taskRecord.setEnterpriseId(task.getEnterpriseId());
                taskRecord.setEnterpriseName(task.getEnterpriseName());
                taskRecord.setActive(1);
                if(listPublic.getInspectResultCode().equals(LISTSTATUSENUM.UNCONFORM.getCode())){
                    taskRecord.setDangerExplain(listPublic.getDangerExplain());
                    taskRecord.setStatus(RECORDSTATUSENUM.MEASURE.getCode());
                    taskRecord.setInspectTablePublicListId(listPublic.getId());
                    taskRecord.setDangerTypeName(listPublic.getDangerType());
                    taskRecord.setDangerLevel(listPublic.getHiddenDangerLevel());
                    taskRecord.setApplyUserId(listPublic.getApplyUserId());
                    taskRecord.setSuggestion(listPublic.getInspectContent());
                    taskRecord.setDangerPosition(listPublic.getDangerPosition());
                    taskRecord.setInspectTime(new Date());
                    taskRecord.setRecordExplain();
                    dangerCountMap.put("dangerCount",dangerCountMap.get("dangerCount")+1);
                    recordList.add(taskRecord);
                }else if(listPublic.getInspectResultCode()
                        .equals(LISTSTATUSENUM.UNAPPLY.getCode())
            ||listPublic.getInspectResultCode()
                        .equals(LISTSTATUSENUM.CONFORM.getCode())){
                    taskRecord.setRemark(listPublic.getRemark());
                    taskRecord.setInspectTablePublicListId(listPublic.getId());
                    if(listPublic.getInspectResultCode()
                            .equals(LISTSTATUSENUM.UNAPPLY.getCode())){
                        taskRecord.setStatus(RECORDSTATUSENUM.UNAPPLY.getCode());
                    }else{
                        taskRecord.setStatus(RECORDSTATUSENUM.FINISH.getCode());
                    }
                    recordList.add(taskRecord);
                }
            });
            dangerCountMap.put("inspectCount",recordList.size());
            taskRecordMapper.insertList(recordList);
        }
        updateTaskCount(dangerCountMap.get("dangerCount"),dangerCountMap.get("inspectCount"),taskId);
        return true;
    }

    private void updateTaskCount(int dangerCount,int inspectCount,int taskId){
        taskMapper.updateDangerCount(dangerCount,inspectCount,taskId);
    }

    public List<DangerInspectListPublic> find(DangerInspectListPublic dangerInspectListPublic) {
        Map<Integer, String> deptNameMap = new HashMap<>();
        //如果需要获取当前公司向下的所有隐患记录，downward为true
        if (dangerInspectListPublic.getDownward()) {
            SysDept sysDept = sysDeptMapper.selectByPrimaryKey(MyShiroUtils.getCompanyId());
            List<SysDept> sysDepts = new ArrayList<>();
            List<SysDept> tempDepts = sysDeptService.getCompanyDepts(sysDept, false, sysDepts);
            List<Integer> sysDeptIds = sysDepts.parallelStream()
                    .map(SysDept::getId).collect(Collectors.toList());
            sysDeptIds.add(MyShiroUtils.getCompanyId());
            List<DangerInspectPublic> dangerInspectPublics = dangerInspectPublicMapper
                    .findDangerInspectByDeptId(sysDeptIds, dangerInspectListPublic.getStartDate()
                            , dangerInspectListPublic.getEndDate());
            List<Integer> dangerInspectPublicIds = dangerInspectPublics.stream().map(DangerInspectPublic::getId)
                    .collect(Collectors.toList());
            dangerInspectListPublic.setDangerInspectPublicIds(dangerInspectPublicIds);
            dangerInspectPublics.forEach(dangerInspectPublic -> {
                deptNameMap.put(dangerInspectPublic.getId(), dangerInspectPublic.getTargetDeptName());
            });
        }
        List<DangerInspectListPublic> dangerInspectLists = dangerInspectListPublicMapper.search(dangerInspectListPublic);
        compareDangerInspectListPicsAndoverTime(dangerInspectLists, deptNameMap);

        return dangerInspectLists;
    }

    public List<DangerInspectListPublic> compareInspectListPicsAndTaskRecord(List<DangerInspectListPublic> listPublicList) {
        List<Integer> listIds = listPublicList.parallelStream()
                .map(DangerInspectListPublic::getId).collect(Collectors.toList());
        List<SysFile> sysFiles = sysFileMapper.findByContentIds(listIds
                , Constant.SysFileType.TASK_TABLE_LIST_FILE.getValue());
        Map<Integer,DangerInspectListPublic> idMap=  listPublicList.stream()
                .collect(Collectors.toMap(DangerInspectListPublic::getId, listPublic -> listPublic));
        sysFiles.forEach(file->{
            file.setUrl(ossDomain+"/"+file.getPath()+"?x-oss-process=image/resize,m_fixed,h_70,w_70");
            file.setOriUrl(ossDomain+"/"+file.getPath());
            idMap.get(file.getContentId()).getDangerPics().add(file);
        });
        List<SafeDangerInspectTaskRecord> taskRecordList=taskRecordMapper.findByInspectListPublicId(listIds);
        taskRecordList.forEach(taskRecord -> {
            idMap.get(taskRecord.getInspectTablePublicListId()).setTaskRecord(taskRecord);
        });
        return idMap.values().stream().collect(Collectors.toList());
    }

    /**
     * 装配隐患检查单中所有隐患条例的相关照片
     * 是否超期
     *
     * @param dangerInspectListPublics
     */
    public void compareDangerInspectListPicsAndoverTime(List<DangerInspectListPublic> dangerInspectListPublics
            , Map<Integer, String> deptName) {
        if (CollectionUtil.isEmpty(dangerInspectListPublics)) {
            return;
        }
        dangerInspectListPublics.parallelStream().forEach(dangerInspectListPublic -> {
            SysFile sysFile = new SysFile();
            sysFile.setContentType(Constant.SysFileType.DANGER_PIC.getValue());//隐患照片
            sysFile.setContentId(dangerInspectListPublic.getId());
            List<SysFile> dangerPics = sysFileMapper.select(sysFile);
            if (CollectionUtil.isNotEmpty(dangerPics)) {
                dangerInspectListPublic.setDangerPics(dangerPics);
            }
            sysFile.setContentType(Constant.SysFileType.DANGER_REFORM_PIC.getValue());//整改后照片
            List<SysFile> changePics = sysFileMapper.select(sysFile);
            if (CollectionUtil.isNotEmpty(changePics)) {
                dangerInspectListPublic.setChangePics(changePics);
            }
            sysFile.setContentType(Constant.SysFileType.SUPERVISE_PIC.getValue());//督办的照片
            List<SysFile> supervisePics = sysFileMapper.select(sysFile);
            if (CollectionUtil.isNotEmpty(supervisePics)) {
                dangerInspectListPublic.setSupervisePics(supervisePics);
            }
            dangerInspectListPublic.setDeptName(deptName.getOrDefault(dangerInspectListPublic.getInspectPublicId(), ""));
            putOverTimeInfo(dangerInspectListPublic);
        });

    }

    /**
     * 设置整改的隐患是否超期，整改超期和督办超期
     *
     * @param dangerInspectListPublic
     */
    private void putOverTimeInfo(DangerInspectListPublic dangerInspectListPublic) {
        Date now = new Date();
        if (ObjectUtil.isNotNull(dangerInspectListPublic.getSuperviseFinishDate())) {
            if (ObjectUtil.isNull(dangerInspectListPublic.getSuperviseReformDate()) &&
                    (now.getTime() > dangerInspectListPublic.getSuperviseFinishDate().getTime())) {
                dangerInspectListPublic.setSuperviseChangeOverTime(true);
            }
            if (ObjectUtil.isNotNull(dangerInspectListPublic.getSuperviseReformDate()) &&
                    (dangerInspectListPublic.getSuperviseReformDate().getTime()
                            > dangerInspectListPublic.getSuperviseFinishDate().getTime())) {
                dangerInspectListPublic.setSuperviseChangeOverTime(true);
            }
        }
        if (ObjectUtil.isNotNull(dangerInspectListPublic.getDeadline())) {
            if (ObjectUtil.isNull(dangerInspectListPublic.getChangeTime())
                    && (now.getTime() > dangerInspectListPublic.getDeadline().getTime())) {
                dangerInspectListPublic.setChangeOverTime(true);
            }
            if (ObjectUtil.isNotNull(dangerInspectListPublic.getChangeTime())
                    && (dangerInspectListPublic.getChangeTime().getTime()
                    > dangerInspectListPublic.getDeadline().getTime())) {
                dangerInspectListPublic.setChangeOverTime(true);
            }
        }
    }
}
